EKSのFargate Profile更新時の失敗談
今回は私がEKSのFargate Profileを更新した際にやってしまった失敗談をご紹介します。
どういう失敗だったか
Fargate Profileを有効化しているのにも関わらず、Fargate上で稼働しているPodがひとつもなかった、さらにそれに気づくのにも遅れた、というものです。
やったこと
Fargate NodeとEC2 Node(マネージド型ノードグループ)、両方を使うEKSクラスターを利用していました。Terraform RegistryにあるEKS moduleを使って以下のように、使用しているNamespace毎にFargate Profileを分けてプロビジョニングしていました。
locals { fargate_profiles = { for ns in local.fargate_namespaces : ns => { name = ns selectors = [ { namespace = ns } ] } } fargate_namespaces = ["kube-system", "hoge", "fuga", "piyo"] } module "eks" { source = "terraform-aws-modules/eks/aws" version = "17.24.0" cluster_name = local.eks_name cluster_version = "1.22" vpc_id = module.vpc.vpc_id (略) node_groups = { (local.node_group_name) = { subnets = module.vpc.private_subnets desired_capacity = 2 max_capacity = 4 min_capacity = 1 instance_types = ["m6i.large"] disk_size = 80 } } fargate_profiles = local.fargate_profiles fargate_subnets = module.vpc.private_subnets }
Namespace毎にFargate Profileを分けたことに特に理由はありませんでした。一方で、分けることのデメリットに後々気づきました。作成と削除にとても時間がかかるのです。
- クラスターのいずれかの Fargate プロファイルが DELETING ステータスである場合は、Fargate プロファイルの削除が完了するのを待ってから、そのクラスターに他のプロファイルを作成する必要があります。
- 一度にクラスター内の 1 つの Fargate プロファイルのみが、DELETING ステータスになることができます。そのクラスター内の他のプロファイルを削除する前に、Fargate プロファイルの削除が完了するまでお待ちください。
上記に書かれているように、Profileの削除はひとつずつ行う必要があり並列ではできません。また作成についてはドキュメントに記述がありませんでしたが、削除時と同じく複数のProfileを並列作成はできず、ひとつずつ行なう必要があります。作成中(=Status
がCREATING
)のProfile xxxがある状態で別のProfile yyyを作成しようとすると以下のエラーになりました。
Cannot create Fargate Profile yyy because cluster (クラスター名) currently has Fargate profile xxx in status CREATING
1Profileの作成・削除あたり数分以上かかることもあるので、これを直列でやるのは遅いです。 というわけで、namespace毎にFargate Profileを作成することは得策ではないと考え、以下のように修正してひとつのProfileに統合することにしました。
locals { fargate_profiles = { + default = { + name = "default" + selectors = concat( + [for ns in local.fargate_namespaces : + { + namespace = ns + } + ] + ) + } - for ns in local.fargate_namespaces : - ns => { - name = ns - selectors = [ - { - namespace = ns - } - ] - } } fargate_namespaces = ["kube-system", "hoge", "fuga", "piyo"] } (略)
この terraform apply
は成功しました。が、この時からFargate Pod上で稼働しているPodがなくなりました。
原因
applyの処理順を確認すると原因がわかりました。
- 既存のFargate Profileを削除 → この時点で、それまでFargate Node上で起動していたPodはすべてEC2 Nodeにスケジュールし直される
- 新Fargate Profile作成 → Fargate Profileが働くのはPod起動時のみ。 1でEC2 Node上で起動し直したPodは対象外
まあよく考えたら分かる話なんですが、気づけなかったです…
対応方法
1. 既存Fargate Profileの削除前に新規Fargate Profileを作成する
- Fargate プロファイルを削除すると、そのプロファイルで Fargate にスケジューリングされていた pods はすべて削除されます。これらの pods が別の Fargateプロファイルと一致する場合、それらのポッドはそのプロファイルで Fargate にスケジューリングされます
Fargate プロファイルの削除 - AWS Fargate プロファイル - Amazon EKSより引用
今回の更新内容を2つにわけて、
- 新Profileのコードを追加してapply
- 旧Profilesのコードを削除してapply
と2回applyするようにすれば、2で「そのプロファイルで Fargate にスケジューリングされていた pods はすべて削除されます」が、「これらの pods が別の Fargateプロファイルと一致する場合、それらのポッドはそのプロファイルで Fargate にスケジューリングされます」に当てはまるので、再びFargate Node上でPodが稼働し始めます。
2. Podのrestart
1は予防策ですが、こちらは事後対応つまりもうすでにEC2 Node上でPodが稼働してしまっている場合の修正方法です。もう一度Podの作成を発生させればFargate Profileをチェックして該当PodをFargate Node上で起動する処理が走りますので、kubectl rollout restart deployments
コマンドでPodの再作成を強制すれば良いです。